/* eslint-disable no-async-promise-executor */
/* eslint-disable no-undef */
/* eslint-disable no-unused-vars */
/**
 * web3 操作
 */
import Web3 from "web3"
import abi from "./abi"
import BigNumber from "bignumber.js";
import store from "@/store"
import { login } from "@/request/api";

/**
 * 补齐64位，不够前面用0补齐
 * @param {*} num 
 * @returns 
 */
export const addPreZero = (num) => {
    var t = (num + '').length,
        s = '';
    for (var i = 0; i < 64 - t; i++) {
        s += '0';
    }
    return s + num;
}
/**
 * 判断系统源 是ios 还是安卓
 */
export const appSource = () => {
    const u = navigator.userAgent;
    const isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
    if (isiOS) {
        return "ios";
    } else {
        return "andriod";
    }
}


export default class Web3Class {
    constructor() {
        this.HttpProvider = "http://127.0.0.1:8545"
        this.collection = "0x2B4FA5EF1d50Fe5BADE2770EB13658caeba73f07"
        // this.collection = store.state.user.token
        this.web3 = null
        this.web3Abi = null
    }
    /**
     * 连接钱包
     */
    async connectWallet() {
        return new Promise((resolve, reject) => {
            if (window.ethereum) {
                window.ethereum.enable().then((res) => {
                    resolve(res[0])
                });
            } else {
                reject("请安装MetaMask钱包");
            }
        });
    }

    /**
     * 初始化
     */
    async init() {
        return new Promise((resolve, reject) => {
            //初始化过程
            if (typeof this.web3 !== 'undefined') {
                this.web3 = new Web3(web3.currentProvider);
                resolve(this.web3)
            } else {
                this.web3 = new Web3(new Web3.providers.HttpProvider(this.HttpProvider));
                resolve(this.web3)
            }
        });
    }
    /**
     * 初始化abi
     * @returns 
     */
    // async initAbi() {
    //     return new Promise((resolve, reject) => {
    //         this.web3Abi = new this.web3.eth.Contract(abi, this.collection);
    //         resolve(this.web3Abi)
    //     });
    // }
    async initAbi(collection = this.collection) {
        return new Promise((resolve, reject) => {
            this.web3Abi = new this.web3.eth.Contract(abi, collection);
            resolve(this.web3Abi)
        });
    }

    async getGasPrice() {
        return new Promise((resolve, reject) => {
            const gasPrice = this.web3.eth.getGasPrice()
            resolve(gasPrice)
        });
    }

    /**
     * 发送
     * @param {*} param0 
     * @returns 
     */
    async send({ from, methodName, data, to, gasPrice }) {
        // console.log(from, methodName, data, to, gasPrice);
        return new Promise((resolve, reject) => {
            if (data) {
                this.web3Abi.methods[methodName](data).send({
                    from,
                }).on('receipt', (res) => {
                    resolve(res)
                }).on('error', (error) => {
                    reject(error)
                })
            } else {
                this.web3Abi.methods[methodName]().send({
                    from,
                    to,
                    gasPrice,
                    gas: 100000
                }).on('receipt', (res) => {
                    resolve(res)
                }).on('error', (error) => {
                    reject(error)
                })
            }
        });
    }

    async send2({ from, methodName, data, to, gasPrice }) {
        return new Promise((resolve, reject) => {
            const num = '0x' + (data * Math.pow(10, 18)).toString(16)
            let obj = {
                from,
                to,

            }
            if (appSource() == 'andriod') {
                obj.gasLimit = '0x2097152'
                // obj.gas = '0x1048576'
            }

            this.web3Abi.methods[methodName](to, num).send({
                ...obj
                // gas: 100000
            }).on('receipt', (res) => {
                resolve(res)
            }).on('error', (error) => {
                reject(error)
            })
        });
    }

    /**
     * 读取
     * @returns 
     */
    async call({ methodName, from, data = 0 }) {
        return new Promise((resolve, reject) => {
            if (data) {
                this.web3Abi.methods[methodName](data).call({ from }, (err, res) => {
                    resolve(res)
                })
            } else {
                this.web3Abi.methods[methodName]().call({ from }, (err, res) => {
                    resolve(res)
                })
            }
        });
    }

    /**
     * 以太币转账
     * @param {*} from 钱包地址
     * @param {*} to  对方地址/合约地址
     * @param {*} value 金额
     * @returns 
     */
    // async sendTransaction(from, to = this.collection, value) {
    //     value = '0x' + (value * Math.pow(10, 18)).toString(16)
    //     return new Promise((resolve, reject) => {
    //         this.web3.eth.sendTransaction({
    //             from,
    //             to,
    //             value
    //         }).then((res) => {
    //             resolve(res)
    //         });
    //     });
    // }

    /**
     * 发送交易
     * @param {String} from 发件人钱包地址
     * @param {String} to 代币地址
     * @param {String} sendType a9059cbb=转账(默认) 095ea7b3=授权转账权限(approve) 
     * sendType = 095ea7b3=授权转账权限 的时候 from=钱包地址 to=合约地址 amount/pow = Math.pow(10, 18)
     * @param {String} collection = 接收人地址
     * @param {Boolea} platform = 是否是平台转账
     * https://docs.metamask.io/guide/sending-transactions.html#transaction-parameters
     * http://cw.hubwiz.com/card/c/metamask-api/1/2/8/
     * @returns 
     */

    async sendTransaction(from, to = this.collection, amount) {
        return new Promise((resolve, reject) => {
            const gas = "0x186A0"
            const gasPrice = "0x3B9ACA00"
            const value = "0x00"
            const sendType = "d91062a9"
            const _amount = new BigNumber(amount).times(Math.pow(10, 18))
            const data = '0x' + sendType + addPreZero(to.substr(2)) + addPreZero(_amount.toString(16))

            const params = [
                {
                    from,//发件人钱包地址 
                    to,//代币地址 
                    // gas, // （可选，默认值：90000）为交易执行提供的气体整数。它将返回未使用的气体。QUANTITY  
                    // gasPrice, // （可选，默认值：待定）用于每个付费气体的gas价格的整数。QUANTITY
                    value, // （可选）与此事务一起发送的值的整数。QUANTITY
                    data,
                },
            ]
            window.ethereum
                .request({
                    method: 'eth_sendTransaction',
                    params
                })
                .then((txHash) => {
                    resolve({ blockHash: txHash })
                })
                .catch((error) => {
                    reject(error)
                });
        })
    }

    // async qsendTransaction({ from, to, gas = '0x186A0', gasPrice = '0x3B9ACA00', value = '0x00', data, collection, sendType = 'd91062a9', amount, platform = false, pow = Math.pow(10, 18) }) {
    //     return new Promise((resolve, reject) => {
    //         const _amount = new BigNumber(amount).times(pow)
    //         if (platform) {
    //             value = addPreZero(_amount.toString(16))
    //         } else {
    //             data = '0x' + sendType + addPreZero(collection.substr(2)) + addPreZero(_amount.toString(16))
    //             // data = '0x' + sendType + addPreZero(collection.substr(2)) + '0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    //             // data = '0x' + sendType + addPreZero(collection.substr(2)) + '00000000000000000000000000000000000000000051b7062aaa69470d1d2711'
    //         }
    //         const params = [
    //             {
    //                 from,//发件人钱包地址 
    //                 to,//代币地址 
    //                 gas, // （可选，默认值：90000）为交易执行提供的气体整数。它将返回未使用的气体。QUANTITY  
    //                 // gasPrice, // （可选，默认值：待定）用于每个付费气体的gas价格的整数。QUANTITY
    //                 value, // （可选）与此事务一起发送的值的整数。QUANTITY
    //                 data,
    //                 // gasLimit: "60000",
    //                 // maxFeePerGas: "1000000",
    //                 // maxPriorityFeePerGas: "10"
    //             },
    //         ]
    //         // console.log(params);
    //         window.ethereum
    //             .request({
    //                 method: 'eth_sendTransaction',
    //                 params
    //             })
    //             .then((txHash) => {
    //                 resolve({ blockHash: txHash })
    //             })
    //             .catch((error) => {
    //                 reject(error)
    //             });
    //     });
    // }

    /**
     * 获取账户信息
     */
    async getAccounts() {
        return new Promise(async (resolve, reject) => {
            let fromAddress = await this.web3.eth.getAccounts()
            resolve(fromAddress[0])
        });
    }
    /**
     * 获取用户信息
     */
    async getUserInfo() {
        const _web3 = new Web3(window.web3.currentProvider)
        // console.log(web3.eth.getAccounts())
        let fromAddress = await _web3.eth.getAccounts()
        _web3.eth.getBalance(fromAddress[0], (err, res) => {
            if (!err) {
                alert("ETH余额==" + res / Math.pow(10, 18));
                //console.log(res)
            }
        })
    }
}
